-- InterfaceM
-- created by panyl
-- 公共接口模块

module("InterfaceM", package.seeall);

-- 迷宫中随机出现怪物
function monsterAppear(element, pos)
    local monsterPos = pos;
    if not monsterPos then
        local arr = {};
        for p = 1, GRID_SIZE do
            local grid = DungeonM.getGridByPos(p);
            if grid.type == GRID_TYPE_EMPTY or
                grid.state == GRID_STATE_DISABLE and not grid.bonus then
                table.insert(arr, p);
            end
        end

        if #arr > 0 then
            local rand = DungeonM.getRandSeed("monster_appear");
            monsterPos = arr[rand % #arr + 1];
        else
            cclog("没有空位置。");
            return false;
        end
    end

    return DungeonM.transGridToMonster(monsterPos, element, "appear");
end

-- 神秘山洞
function misticCave(pos, option)
    local grid = DungeonM.getGridByPos(pos);
    if grid.type ~= GRID_TYPE_MISTIC_CAVE then
        return false;
    end

    -- 如果还未翻开或者已经无效了
    if not grid:isOpened() or grid.state == GRID_STATE_DISABLE then
        return false;
    end

    -- 如果是选项1
    if option == 1 then
        -- action就不要再次添加了
        return DungeonActionM.go("do_building_bonus", pos), true;
    end

    -- 次数
    local mistake = grid.mistake or 0;
    if mistake >= grid.mistake_limit then
        return false;
    end

    -- 判断位置
    local arr = {};
    for pos = 1, GRID_SIZE do
        local grid = DungeonM.getGridByPos(pos);
        if grid.type == GRID_TYPE_EMPTY or
            grid.state == GRID_STATE_DISABLE and not grid.bonus then
            table.insert(arr, pos);
        end
    end

    -- 没有空位了
    if #arr <= 0 then
        return false;
    end

    -- 随机一个元素
    arr = grid.robbers or {};
    if #arr <= 0 then
        return false;
    end

    local rand = DungeonM.getRandSeed("mistic_cave");
    local element = arr[rand % #arr + 1];

    -- 召唤两只
    local count = 0;
    repeat
        if not monsterAppear(element) then
            break;
        end

        count = count + 1;
    until count >= 2;
    if count <= 0 then
        return false;
    end

    -- 失误次数++
    grid.mistake = mistake + 1;

    EventMgr.fire(event.PLAYER_MOVE, pos);

    -- 抛出遭遇强盗事件
    EventMgr.fire(event.MISTIC_CAVE_ROBBER, { ["count"] = count });

    return true;
end

-- 狮身人面像猜谜
function sphinxRiddle(pos, option)
    local grid = DungeonM.getGridByPos(pos);

    -- 不是狮身人面像
    if grid.type ~= GRID_TYPE_SPHINX then
        return false;
    end

    -- 状态不对
    if not grid:isOpened() or grid.state == GRID_STATE_DISABLE then
        return false;
    end

    local class = grid.riddle_class;
    local riddleId = grid.riddle_id;

    -- 先标记状态
    grid:changeState(GRID_STATE_DISABLE);

    -- 猜谜语
    BonusM.clearBonusCollect();
    BonusM.startBonusCollect();
    local ret = RiddleM.guessRiddle(class, riddleId, option, {["pos"] = pos,});
    BonusM.endBonusCollect();
    local bonus = BonusM.getBonusCollect();

    if #bonus == 0 then
        bonus = { ["bonus"] = {} };
    else
        bonus = { ["bonus"] = bonus[1] };
    end

    -- 抛出通用建筑奖励事件
    EventMgr.fire(event.COMM_BUILDING_BONUS, {
        ["pos"]   = pos,
        ["type"]  = grid.type,
        ["bonus"] = bonus,
    });

    EventMgr.fire(event.PLAYER_MOVE, pos);

    if DungeonM.isCostRound(grid) then
        -- 抛出一个回合事件
        EventMgr.fire(event.COMBAT_ROUND, { ["pos"] = pos, ["isDelay"] = true, } );
    end

    BonusM.clearBonusCollect();

    -- 抛出狮身人面像答案事件
    answer = iif(ret, 1, 0);
    EventMgr.fire(event.SPHINX_ANSWER, { ["answer"] = answer } );

    return answer;
end

-- 解密基本属性
function decodeAttribs(user)
    local attribs = {"hp", "mp", "attack", "magic", "search_point"};
    local ret = {};
    for _, attrib in pairs(attribs) do
        ret[attrib] = user:attribDecode(attrib);
    end

    return ret;
end

-- 计算基础属性（没有buff、debuff、special加成的属性）
function calcBaseAttrib(who, attrib)
    -- 清空所有buff、debuff、special
    local prop = who.dbase:queryTemp("prop") or {};
    local propBuff = prop.buff or {};
    local propDebuff = prop.debuff or {};
    local propSpecial = prop.special or {};
    PropM.deleteProp(who, "buff");
    PropM.deleteProp(who, "debuff");
    PropM.deleteProp(who, "special");

    -- 清空战斗状态
    local combatStatus = CombatStatusM.updateStatus(who, {});

    local ret;

    -- 指定了某个属性
    if type(attrib) == "string" then
        ret = who:queryAttrib(attrib);
    else
        ret = {
            ["attack"] = who:queryAttrib("attack"),
            ["magic"]  = who:queryAttrib("magic"),
            ["max_hp"] = who:queryAttrib("max_hp"),
            ["max_mp"] = who:queryAttrib("max_mp"),
        };
    end

    -- 有状态的附加回去
    if #propBuff > 0 then
        PropM.multiRecord(who, propBuff, "buff");
    end
    if #propDebuff > 0 then
        PropM.multiRecord(who, propDebuff, "debuff");
    end
    if #propSpecial > 0 then
        PropM.multiRecord(who, propSpecial, "special");
    end

    -- 还原战斗状态
    CombatStatusM.updateStatus(who, combatStatus);

    return ret;
end

-- 领取书籍
function bookshelf(pos, index)
    -- 领取书籍
    local gridData = DungeonM.getGridByPos(pos);
    local bonus = gridData.bonus or {};
    local remainGrid = false;

    if bonus[index] then
        local options = gridData.options or {};

        -- 判断是否已经领取
        if table.indexOf(options, index) > 0 then
            return false;
        end

        table.insert(options, index);
        gridData.options = options;

        if #gridData.options < #gridData.bonus then
            remainGrid = true;
        else
            -- 先标记状态
            local grid = DungeonM.getCurrentDungeon();
            grid[gridData:getPos()]:changeState(GRID_STATE_DISABLE);
        end

        BonusM.clearBonusCollect();
        BonusM.startBonusCollect();

        BonusM.doBonus(bonus[index], "Bookshelf");

        -- 提示 "你拿取了《xxx》"
        doAlert(string.format(getLocStr("get_book"), ItemM.query(bonus[index][2], "name")));

        BonusM.endBonusCollect();

        local bonus = BonusM.getBonusCollect();
        if #bonus == 0 then
            bonus = { ["bonus"] = {} };
        else
            bonus = { ["bonus"] = bonus };
        end

        -- 抛出通用建筑奖励事件
        EventMgr.fire(event.COMM_BUILDING_BONUS, {
            ["pos"]   = gridData:getPos(),
            ["type"]  = GRID_TYPE_BOOKSHELF,
            ["bonus"] = bonus,
            ["remainGrid"] = remainGrid,
        });

        BonusM.clearBonusCollect();
        return true;
    end
end
